package com.mall.www.service.impl;

import com.mall.www.common.StatusCode;
import com.mall.www.common.dto.IntegralRecordDto;
import com.mall.www.entity.*;
import com.mall.www.exception.ServiceException;
import com.mall.www.mapper.*;
import com.mall.www.service.IntegralService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 积分
 * <p>
 * 获取
 * 注册完成后加积分
 * 完善个人信息后加积分
 * 评论加评分
 * 下单完成后计算积分进入冻结状态
 * 确认收货后解除冻结状态
 * <p>
 * <p>
 * 消耗
 * 兑换商品
 * <p>
 * <p>
 * 其他
 * 查询用户的积分记录
 * 查询用户积分兑换的记录
 */
@Service
public class IntegralServiceImpl implements IntegralService {
    public static final long REGISTER = 1;
    public static final long IMPROVE_PERSONAL_INFORMATION = 2;
    public static final int ZERO = 0;
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final String ORDER = "订单";
    @Resource
    IntegralMapper integralMapper;

    @Resource
    IntegralChannelMapper integralChannelMapper;

    @Resource
    IntegralItemMapper integralItemMapper;

    @Resource
    IntegralProductMapper integralProductMapper;

    @Resource
    IntegralRecordMapper integralRecordMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    OrderMapper orderMapper;

    @Resource
    AddressMapper addressMapper;

    /**
     * 注册完成后加积分
     * 调用该方法请处理异常
     *
     * @param userId 用户id
     * @return
     */
    @Transactional
    @Override
    public boolean register(Long userId) {
        boolean flag = false;
        try {
            //根据用户id和渠道id查询积分明细信息
            IntegralItem integralItem = integralItemMapper.selectByUserIdAndChannelId(userId, this.REGISTER);
            //判断积分明细信息是否不为空
            if (integralItem != null) {
                //不为空 已领取过注册获得的积分
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            IntegralChannel integralChannel = integralChannelMapper.selectByPrimaryKey(this.REGISTER);
            integralItem = new IntegralItem();
            //设置用id
            integralItem.setUserId(userId);
            //设置状态 1 收入
            integralItem.setStatus(this.ONE);
            //设置来源或者用途
            integralItem.setSourceOrUse(integralChannel.getChannelName());
            //设置渠道id
            integralItem.setIntegralChannelId(integralChannel.getIntegralChannelId());
            //设置积分数
            integralItem.setPoint(integralChannel.getPoint());
            //保存积分明细记录
            int i = integralItemMapper.insertSelective(integralItem);
            if (i <= 0) {
                //添加失败
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            //设置用户的总积分
            //根据用户id获取积分信息
            Integral temp = integralMapper.selectByUserId(userId);
            //判断积分信息是否为空
            if (temp == null) {
                //添加积分信息
                User user = userMapper.selectByUserId(userId);
                temp = new Integral();
                temp.setUserId(Long.valueOf(user.getId()));
                temp.setUsername(user.getName());
                temp.setPoint(integralChannel.getPoint());
                int i1 = integralMapper.insertSelective(temp);
                if (i1 <= 0) {
                    return false;
                }
            }
            //修改用户的积分
            flag = updatePoint(temp, integralChannel.getPoint());
        } catch (Exception e) {
            throw new ServiceException(StatusCode.SERVER_ERROR);
        } finally {
            return flag;
        }
    }

    /**
     * 完善个人信息后加积分
     * 调用该方法请处理异常
     *
     * @param userId 用户id
     * @return
     */
    @Transactional
    @Override
    public boolean improvePersonalInformation(Long userId) {
        boolean flag = false;
        try {
            //根据用户id和渠道id积分明细信息
            IntegralItem integralItem = integralItemMapper.selectByUserIdAndChannelId(userId, this.IMPROVE_PERSONAL_INFORMATION);
            //判断积分明细信息是否不为空
            if (integralItem != null) {
                //不为空 已领取过注册获得的积分
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            //根据分类渠道id获取渠道信息
            IntegralChannel integralChannel = integralChannelMapper.selectByPrimaryKey(this.IMPROVE_PERSONAL_INFORMATION);

            //设置积分明细信息
            integralItem = new IntegralItem();
            //用户id
            integralItem.setUserId(userId);
            //状态 收入
            integralItem.setStatus(this.ONE);
            //来源
            integralItem.setSourceOrUse(integralChannel.getChannelName());
            //积分数目
            integralItem.setPoint(integralChannel.getPoint());
            //渠道id
            integralItem.setIntegralChannelId(integralChannel.getIntegralChannelId());

            //保存积分明细信息
            int i = integralItemMapper.insertSelective(integralItem);

            if (i <= 0) {
                //添加失败
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }

            //设置用户的总积分
            //根据用户id获取积分信息
            Integral temp = integralMapper.selectByUserId(userId);
            //判断积分信息是否为空
            if (temp == null) {
                //添加积分信息
                User user = userMapper.selectByUserId(userId);
                temp = new Integral();
                temp.setUserId(Long.valueOf(user.getId()));
                temp.setUsername(user.getName());
                temp.setPoint(integralChannel.getPoint());
                int i1 = integralMapper.insertSelective(temp);
                if (i1 <= 0) {
                    return false;
                }
            }
            //修改用户的积分
            flag = updatePoint(temp, integralChannel.getPoint());
        } catch (Exception e) {
            throw new ServiceException(StatusCode.SERVER_ERROR);
        } finally {
            return flag;
        }
    }

    /**
     * 下单完成后计算积分进入冻结状态
     * 调用该方法请处理异常
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return
     */
    @Transactional
    @Override
    public boolean toCompleteTheOrder(Long userId, Long orderId) {
        boolean flag = false;
        try {
            //根据用户id和订单id获取积分明细信息
            IntegralItem integralItem = integralItemMapper.selectByUserIdAndOrderId(userId, orderId);
            //判断是否不为空
            if (integralItem != null) {
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            //根据订单id查询订单信息
            Order order = orderMapper.selectByOrderId(orderId);
            //设置积分明细信息
            integralItem = new IntegralItem();
            //订单id
            integralItem.setOrderId(orderId);
            //用户id
            integralItem.setUserId(userId);
            //状态 冻结
            integralItem.setStatus(this.ZERO);
            //来源
            integralItem.setSourceOrUse(this.ORDER + order.getOrderNumber());
            //积分数量
            integralItem.setPoint(order.getGiftPoint());
            //保存 积分明细信息
            int i = integralItemMapper.insertSelective(integralItem);
            if (i <= 0) {
                //添加失败
                flag = false;
            }
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return flag;
        }
    }

    /**
     * 确认收货后解除冻结状态
     * 调用该方法请处理异常
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return
     */
    @Transactional
    @Override
    public boolean confirmReceipt(Long userId, Long orderId) {
        boolean flag = false;
        try {
            //根据用户id和订单id获取积分明细信息
            IntegralItem integralItem = integralItemMapper.selectByUserIdAndOrderId(userId, orderId);
            if (integralItem == null) {
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            integralItem.setStatus(this.ONE);
            int i = integralItemMapper.updateByPrimaryKeySelective(integralItem);
            if (i <= 0) {
                //添加失败
                flag = false;
            }
            //设置用户的总积分
            //根据用户id获取积分信息
            Integral temp = integralMapper.selectByUserId(userId);
            //判断积分信息是否为空
            if (temp == null) {
                //添加积分信息
                User user = userMapper.selectByUserId(userId);
                temp = new Integral();
                temp.setUserId(Long.valueOf(user.getId()));
                temp.setUsername(user.getName());
                temp.setPoint(integralItem.getPoint());
                int i1 = integralMapper.insertSelective(temp);
                if (i1 <= 0) {
                    return false;
                }
            }
            //修改用户的积分
            flag = updatePoint(temp, integralItem.getPoint());
        } catch (Exception e) {

        } finally {
            return flag;
        }
    }

    /**
     * 兑换商品
     *
     * @param integralRecordDto
     * @return
     */
    @Transactional
    @Override
    public boolean conversion(IntegralRecordDto integralRecordDto) {
        boolean flag = false;
        try {
            IntegralProduct integralProduct = integralProductMapper.selectByProductId(integralRecordDto.getProductId());
            if (integralProduct == null) {
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            Integral integral = integralMapper.selectByUserId(integralRecordDto.getUserId());
            if (integral.getPoint() < integralRecordDto.getQuantity() * integralProduct.getPointPrice()) {
                throw new ServiceException(StatusCode.SERVER_ERROR);
            }
            IntegralRecord integralRecord = new IntegralRecord();
            integralRecord.setUserId(integralRecordDto.getUserId());
            integralRecord.setQuantity(integralRecordDto.getQuantity());
            integralRecord.setPresentName(integralProduct.getProductName());
            integralRecord.setPointPrice(integralProduct.getPointPrice());
            integralRecord.setName(integralRecordDto.getName());
            integralRecord.setArea(integralRecordDto.getArea());
            integralRecord.setDetailAddress(integralRecordDto.getDetailAddress());
            integralRecord.setPhone(integralRecordDto.getPhone());
            //保存积分兑换记录
            int i = integralRecordMapper.insertSelective(integralRecord);
            if (i <= 0) {
                flag = false;
            }
            flag = updatePoint(integral, ZERO - integralRecordDto.getQuantity() * integralProduct.getPointPrice());
        } catch (Exception e) {
            throw new ServiceException(StatusCode.SERVER_ERROR);
        } finally {
            return flag;
        }
    }

    private boolean updatePoint(Integral integral, int point) {
        boolean flag = false;
        try {
            integral.setPoint(integral.getPoint() + point);
            int i = integralMapper.updateByPrimaryKeySelective(integral);
            if (i <= 0) {
                flag = false;
            }
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return flag;
        }
    }
}
